package org.feifei.order.service.impl;

import com.sun.org.apache.bcel.internal.generic.NEW;
import org.feifei.basic.service.impl.BaseServiceImpl;
import org.feifei.basic.util.CodeGenerateUtils;
import org.feifei.basic.util.LoginContextUtil;
import org.feifei.basic.util.PageList;
import org.feifei.order.domain.AdoptOrder;
import org.feifei.order.domain.OrderAddress;
import org.feifei.order.mapper.AdoptOrderMapper;
import org.feifei.order.mapper.OrderAddressMapper;
import org.feifei.order.query.AdoptOrderQuery;
import org.feifei.order.service.AdoptOrderService;
import org.feifei.org.domain.Employee;
import org.feifei.org.mapper.EmployeeMapper;
import org.feifei.pay.constants.PayConstants;
import org.feifei.pay.domain.PayBill;
import org.feifei.pay.mapper.PayBillMapper;
import org.feifei.pay.service.PayBillService;
import org.feifei.pet.domain.Pet;
import org.feifei.pet.mapper.PetMapper;
import org.feifei.quartz.constant.JobConstants;
import org.feifei.quartz.dto.QuartzJobInfo;
import org.feifei.quartz.service.QuartzService;
import org.feifei.user.domain.LoginInfo;
import org.feifei.user.domain.User;
import org.feifei.user.domain.UserAddress;
import org.feifei.user.mapper.UserAddressMapper;
import org.feifei.user.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 宠物收养Service的实现类
 */
@Service
public class AdoptOrderServiceImpl extends BaseServiceImpl<AdoptOrder> implements AdoptOrderService {

    @Resource
    private PetMapper petMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserAddressMapper userAddressMapper;

    @Resource
    private AdoptOrderMapper adoptOrderMapper;

    @Resource
    private OrderAddressMapper orderAddressMapper;

    @Resource
    private EmployeeMapper employeeMapper;

    @Resource
    private PayBillMapper payBillMapper;

    @Resource
    private PayBillService payBillService;

    @Resource
    private QuartzService quartzService;
    

    @Override
    public String adoptOrderSubmit(Map<String, Object> params, HttpServletRequest request) {
        Long petId = Long.valueOf(params.get("pet_id").toString());
        // 1.设置该宠物为下架状态同时设置下架时间
        Pet pet = petMapper.get(petId);
        pet.setState(0).setOffsaletime(new Date());

        // 2. 从请求获取用户id，同时给用户绑定上宠物id
        LoginInfo loginInfo = LoginContextUtil.getLoginInfo(request);
        User user = userMapper.getByLoginId(loginInfo.getId());

        // 保存当前宠物的信息
        pet.setUser_id(user.getId());
        petMapper.update(pet);


        //送货方式 - 默认送宠上门
        Integer service_method = Integer.parseInt(params.get("service_method").toString());
        //支付方式
        Long payType = Long.parseLong(params.get("pay_method").toString());

        // 通过用户传来的地址id获取地址
        long addressId = Long.parseLong(params.get("address_id").toString());

        // 生成订单
        // 3.1 创建订单 - 通过pet 和 user 对象生成
        AdoptOrder adoptOrder = petUser2AdoptOrder(pet,user);
        adoptOrderMapper.save(adoptOrder); // 保存订单获取自增长id

        // 3.2 根据地址id获取用户的地址，赋值给订单
        // 3.3.订单地址对象中设置订单id和orderSn
        // 3.4.添加到数据库【订单地址不会变化，但是用户的地址可以变化】
        UserAddress userAddress = userAddressMapper.get(addressId);
        OrderAddress orderAddress = userAddress2OrderAddress(userAddress,adoptOrder);
        
        // 保存订单地址
        orderAddressMapper.save(orderAddress);
        // 4.支付 @TODO
        // 4.1生成支付单 t_pay_bill
        PayBill payBill = initPayBil(user, payType, adoptOrder, orderAddress);
        payBillMapper.save(payBill);
        //4.2.调用第三方的支付接口【支付宝】去支付

        //5.添加定时任务 - 超时未支付取消订单
        QuartzJobInfo info = new QuartzJobInfo();
        info.setType(JobConstants.OVER_TIME_NO_PAY_ADOPT);
        info.setFireDate(payBill.getLastPayTime());
        info.setJobName(JobConstants.OVER_TIME_NO_PAY_ADOPT + adoptOrder.getPaySn());

        Map<String, Object> map = new HashMap<>();
        //传递订单id - 如果时间过期了要取消订单 - 设置订单的state=-1  - 通过orderId设置state=-1
        map.put("orderId",adoptOrder.getId());
        info.setParams(map);

        // 添加一个定时任务
        quartzService.add(info);
        System.out.println("定时任务【"+info.getJobName() + "】创建了");


        return payBillService.payRequest(payBill);
    }

    /**
     * 初始化支付单的方法
     * @param user
     * @param payType
     * @param adoptOrder
     * @param orderAddress
     * @return
     */
    private PayBill initPayBil(User user, Long payType, AdoptOrder adoptOrder, OrderAddress orderAddress) {
        PayBill payBill = new PayBill();
        payBill.setDigest(adoptOrder.getDigest())
                .setMoney(adoptOrder.getPrice())
                .setUnionPaySn(adoptOrder.getPaySn())
                .setNickName(user.getUsername())
                .setLastPayTime(new Date(System.currentTimeMillis() + PayConstants.ORDER_TIMEOUT))
                .setBusinessKey(adoptOrder.getId())
                .setBusinessType(PayConstants.BUSINESS_TYPE_ADOPT)
                .setShop_id(adoptOrder.getShop_id())
                .setUser_id(user.getId())
                .setPayChannel(payType);
        return payBill;
    }


    @Override
    public PageList<AdoptOrder> adminAdoptOrder(AdoptOrderQuery adoptOrderQuery, HttpServletRequest request) {
        LoginInfo loginInfo = LoginContextUtil.getLoginInfo(request);
        Employee employee = employeeMapper.findByLoginID(loginInfo.getId());
        adoptOrderQuery.setShopId(employee.getShop_id());
        return super.listByPage(adoptOrderQuery);
    }

    @Override
    public PageList<AdoptOrder> userAdoptOrder(AdoptOrderQuery adoptOrderQuery, HttpServletRequest request) {
        LoginInfo loginInfo = LoginContextUtil.getLoginInfo(request);
        User user = userMapper.getByLoginId(loginInfo.getId());
        adoptOrderQuery.setUserId(user.getId());

        return super.listByPage(adoptOrderQuery);
    }


    @Override
    public void cancelOrder(long oid) {
        AdoptOrder adoptOrder = adoptOrderMapper.get(oid);
        adoptOrder.setState(-1);//取消订单
        adoptOrderMapper.update(adoptOrder);

        String paySn = adoptOrder.getPaySn();
        PayBill payBill = payBillMapper.loadByUnionPaySn(paySn);
        payBill.setState(-1);//取消支付单
        payBillMapper.update(payBill);
        System.out.println("订单取消成功...");
    }

    /**
     * 将用户地址复制给订单地址
     * @param userAddress
     * @param adoptOrder
     * @return
     */
    private OrderAddress userAddress2OrderAddress(UserAddress userAddress, AdoptOrder adoptOrder) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress,orderAddress);

        orderAddress.setOrder_id(adoptOrder.getId());
        orderAddress.setOrderSn(adoptOrder.getOrderSn());

        orderAddress.setCreateTime(new Date());
        return orderAddress;
    }

    /**
     * 将宠物信息复制给收养订单
     * @param pet
     * @param user
     * @return
     */
    private AdoptOrder petUser2AdoptOrder(Pet pet, User user) {
        AdoptOrder order = new AdoptOrder();
        order.setDigest("[摘要]对"+pet.getName()+"领养订单！");
        order.setState(0);//待支付 以支付1 取消-1
        order.setPrice(pet.getSaleprice()); //领养订单设置销售价
        String orderSn = CodeGenerateUtils.generateOrderSn(user.getId());
        order.setOrderSn(orderSn);
        //paySn - 支付单唯一单号 - 支付的时候做
        order.setPaySn(CodeGenerateUtils.generateUnionPaySn());
        //最后支付时间 - 24小时不支付就取消
        order.setLastPayTime(new Date(System.currentTimeMillis() + PayConstants.ORDER_TIMEOUT));
        //lastcomfirmtime - 支付之后再整
        order.setPet_id(pet.getId());
        order.setUser_id(user.getId());
        order.setShop_id(pet.getShop_id());
        //lastcomfirmtime - 店铺给用户 - 不用倒计时定时器
        return order;
    }


}